package com.xyht.sca_s.student_manage_system.modules.bigData.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.bigData.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.bigData.service.SmsBasicInformationService;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgStructure;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgUserRelation;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgStructureMapper;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgUserRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.schoolEditor.entity.SmsSchoolEditor;
import com.xyht.sca_s.student_manage_system.modules.schoolEditor.mapper.SmsSchoolEditorMapper;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsStudentInfo;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.teacher.entity.SmsTeacherInfo;
import com.xyht.sca_s.student_manage_system.modules.teacher.entity.SmsUserTeacherRelation;
import com.xyht.sca_s.student_manage_system.modules.teacher.mapper.SmsTeacherInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.teacher.mapper.SmsUserTeacherRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.teachersDemeanor.mapper.SmsTeachersDemeanorMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.bigData.constant.EnrolStudentSexConstant.STU_SEX_BOY;
import static com.xyht.sca_s.student_manage_system.modules.bigData.constant.EnrolStudentSexConstant.STU_SEX_GIRL;
import static com.xyht.sca_s.student_manage_system.modules.bigData.constant.OrgLevelConstant.ORG_LEVEL_COLLEGE;
import static com.xyht.sca_s.student_manage_system.modules.bigData.constant.ProfessionalConstant.PROFESSIONAL_STU_MAJOR;


/**
 * <p>
 * 基础信息
 * </p>
 *
 * @author XYHT
 * @since 2023-08-31
 */
@Service
public class SmsBasicInformationServiceImpl  implements SmsBasicInformationService {

    @Resource
    private SmsStudentInfoMapper smsStudentInfoMapper;
    @Resource
    private SmsTeacherInfoMapper smsTeacherInfoMapper;
    @Resource
    private SmsSchoolEditorMapper smsSchoolEditorMapper;
    @Resource
    private SmsTeachersDemeanorMapper smsTeachersDemeanorMapper;
    @Resource
    private SmsOrgStructureMapper orgStructureMapper;
    @Resource
    private SmsOrgUserRelationMapper orgUserRelationMapper;
    @Resource
    private SmsUserTeacherRelationMapper userTeacherRelationMapper;

    @Override
    public ResponseResult getBasicInformation() {
        SmsBasicInformationResp informationResp = new SmsBasicInformationResp();
        SmsSchoolEditor smsSchoolEditor = smsSchoolEditorMapper.selectOne(new LambdaQueryWrapper<SmsSchoolEditor>()
        .orderByDesc(SmsSchoolEditor::getCreateTime));
        //校园简介
        if(!isNullOrEmpty(smsSchoolEditor)){
            SmsSchoolIntroductionResp smsSchoolIntroductionResp = new SmsSchoolIntroductionResp();
            smsSchoolIntroductionResp.setSchoolPicture(smsSchoolEditor.getLogo());//校园图片
            smsSchoolIntroductionResp.setDescribe(smsSchoolEditor.getSchoolProfile());//校园简介
            informationResp.setSchoolIntroduction(smsSchoolIntroductionResp);
        }
        //年级概况
        SmsGradeOverviewAndSumResp smsGradeOverviewAndSumResp = new SmsGradeOverviewAndSumResp();
        List<SmsGradeOverviewResp> gradeOverviewList = new ArrayList<>();
        List<Map<String, Object>> maps = smsStudentInfoMapper.selectMaps(new QueryWrapper<SmsStudentInfo>()
                .select("count(*) as gradeCount,stu_grade as grade")
                .lambda()
                .orderByDesc(SmsStudentInfo::getStuGrade)
                .groupBy(SmsStudentInfo::getStuGrade));
        int studentSum = 0;
        if(maps != null && maps.size() > 0) {
            for (Map<String, Object> map : maps) {
                SmsGradeOverviewResp gradeOverviewResp = new SmsGradeOverviewResp();
                SmsGradeOverviewResp smsGradeOverviewResp = JSONObject.parseObject(JSONObject.toJSONString(map), SmsGradeOverviewResp.class);
                if(!isNullOrEmpty(smsGradeOverviewResp)) {
                    gradeOverviewResp.setGrade(smsGradeOverviewResp.getGrade());//年级名
                    gradeOverviewResp.setGradeCount(smsGradeOverviewResp.getGradeCount());//年级总数
                    studentSum += smsGradeOverviewResp.getGradeCount();
                }
                gradeOverviewList.add(gradeOverviewResp);
            }
        }
        smsGradeOverviewAndSumResp.setGradeOverview(gradeOverviewList);
        smsGradeOverviewAndSumResp.setStudentSum(studentSum);//学生总数
        informationResp.setGradeOverviewAndSum(smsGradeOverviewAndSumResp);
        //教师风采
        List<SmsTeachersDemeanorResp> teachersDemeanorList;
        teachersDemeanorList = smsTeachersDemeanorMapper.selectList(null)
                .stream()
                .map(smsTeachersDemeanor -> {
                    SmsTeachersDemeanorResp teachersDemeanorResp = new SmsTeachersDemeanorResp();
                    SmsTeacherInfo smsTeacherInfo = smsTeacherInfoMapper.selectById(smsTeachersDemeanor.getTeacherId());
                    if(!isNullOrEmpty(smsTeacherInfo)){
                        teachersDemeanorResp.setTeacherPic(smsTeacherInfo.getTchPic());//头像
                        teachersDemeanorResp.setTeacherName(smsTeacherInfo.getTchName());//姓名
                        teachersDemeanorResp.setTeacherTitle(smsTeacherInfo.getTchTitle());//教师职级(职称)
                        teachersDemeanorResp.setTeacherPost(smsTeacherInfo.getTchPost());//教师职位(职务)
                    }
                    return teachersDemeanorResp;
                })
                .collect(Collectors.toList());
        informationResp.setTeachersDemeanor(teachersDemeanorList);
        return CommonResult.success(informationResp);
    }

    @Override
    public ResponseResult getTeachersOverview(String beginTimeStr, String endTimeStr) {
        if(isNullOrEmpty(beginTimeStr,endTimeStr)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        int beginInt = Integer.parseInt(beginTimeStr);
        int endInt = Integer.parseInt(endTimeStr);
        if(beginInt > endInt){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<SmsTeachersOverviewResp> teachersOverviewList = getThisYearStudentAndTeacherSum(beginInt, endInt,null);
        return CommonResult.success(teachersOverviewList);
    }



    @Override
    public ResponseResult getTeachersRatio(String thisYear) {
        if(isNullOrEmpty(thisYear)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        int beginInt = Integer.parseInt(thisYear);
        SmsTeachersRatioResp smsTeachersRatioResp = new SmsTeachersRatioResp();
        List<SmsTeachersOverviewResp> teachersOverviewList = getThisYearStudentAndTeacherSum(beginInt, beginInt,null);
        if(teachersOverviewList.size() > 0) {
            SmsTeachersOverviewResp teachersOverviewResp = teachersOverviewList.get(0);
            Integer studentSum = teachersOverviewResp.getStudentSum();
            Integer teacherSum = teachersOverviewResp.getTeacherSum();
            //学生 老师占比
            if(studentSum + teacherSum == 0){
                smsTeachersRatioResp.setStudentRatio(0);
                smsTeachersRatioResp.setTeacherRatio(0);
            }else {
                double studentRatio = Math.ceil((double) studentSum / (studentSum + teacherSum) *100);
                double teacherRatio = Math.floor((double) teacherSum / (studentSum + teacherSum) *100);
                smsTeachersRatioResp.setStudentRatio((int)studentRatio);
                smsTeachersRatioResp.setTeacherRatio((int)teacherRatio);
            }
            smsTeachersRatioResp.setThisYear(thisYear);
            smsTeachersRatioResp.setStudentCount(studentSum);
            smsTeachersRatioResp.setTeacherCount(teacherSum);

        }
        return CommonResult.success(smsTeachersRatioResp);
    }

    @Override
    public ResponseResult getProfessionalOverview(String startDate) {
        if(isNullOrEmpty(startDate)){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        int beginInt = Integer.parseInt(startDate);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, beginInt);
        calendar.set(Calendar.MONTH,11);
        Date endDate = TimeUtil.GetEndDateOfMonth(calendar.getTime());
        QueryWrapper<SmsStudentInfo> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper
                .select("count(*) as professionalSum,stu_major AS professional")
                .lambda()
                .le(SmsStudentInfo::getCreateTime,endDate)
                .groupBy(SmsStudentInfo::getStuMajor);
        List<Map<String, Object>> studentMaps = smsStudentInfoMapper.selectMaps(studentQueryWrapper);
        List<SmsProfessionalOverviewResp> professionalOverviewList = new ArrayList<>();
        if (studentMaps != null && studentMaps.size() > 0) {
            for (Map<String, Object> studentMap : studentMaps) {
                SmsProfessionalOverviewResp professionalOverviewResp = JSONObject.parseObject(JSON.toJSONString(studentMap), SmsProfessionalOverviewResp.class);
                professionalOverviewResp.setProfessional(professionalOverviewResp.getProfessional());//专业
                professionalOverviewResp.setProfessionalSum(professionalOverviewResp.getProfessionalSum());//该专业学生数
                professionalOverviewList.add(professionalOverviewResp);
            }
        }
        return CommonResult.success(professionalOverviewList);
    }

    @Override
    public ResponseResult getProfessional() {
        List<SmsOrgStructure> smsOrgStructures = orgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getLevel, PROFESSIONAL_STU_MAJOR)
                .orderByAsc(SmsOrgStructure::getId));
        List<SmsOrgStructureListReq> smsOrgStructureList = new ArrayList<>();
        if(smsOrgStructures != null && smsOrgStructures.size() > 0){
            for (SmsOrgStructure smsOrgStructure : smsOrgStructures) {
                SmsOrgStructureListReq smsOrgStructureListReq = new SmsOrgStructureListReq();
                smsOrgStructureListReq.setOrgName(smsOrgStructure.getOrgName());
                smsOrgStructureListReq.setId(smsOrgStructure.getId());
                smsOrgStructureList.add(smsOrgStructureListReq);
            }
        }
        return CommonResult.success(smsOrgStructureList);
    }

    @Override
    public ResponseResult getTchTitleSum() {
        //院系和(职称+数量)
        List<SmsTeacherTitleResp> teacherTitleList = new ArrayList<>();

        //查询组织是院系
        List<SmsOrgStructure> smsOrgStructures = orgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>().eq(SmsOrgStructure::getLevel, ORG_LEVEL_COLLEGE));
        if(smsOrgStructures.isEmpty()){
            return CommonResult.success(teacherTitleList);
        }
        //查询有那些职称
        QueryWrapper<SmsTeacherInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .select("tch_title")
                .lambda()
                .isNotNull(SmsTeacherInfo::getTchTitle)
                .groupBy(SmsTeacherInfo::getTchTitle);
        List<String> titleList = smsTeacherInfoMapper.selectList(queryWrapper).stream().map(SmsTeacherInfo::getTchTitle).collect(Collectors.toList());

        for (SmsOrgStructure smsOrgStructure : smsOrgStructures) {
                SmsTeacherTitleResp smsTeacherTitleResp = new SmsTeacherTitleResp();
                String orgId = smsOrgStructure.getId().toString();//组织id
                String orgName = smsOrgStructure.getOrgName();//院系名称
                smsTeacherTitleResp.setTchCollege(orgName);
                teacherTitleList.add(smsTeacherTitleResp);
                //组织和用户的关系
                List<SmsOrgUserRelation> smsOrgUserRelations =
                        orgUserRelationMapper.selectList(new LambdaQueryWrapper<SmsOrgUserRelation>().eq(SmsOrgUserRelation::getOrgId, orgId));
                if (smsOrgUserRelations.isEmpty()) {
                    getContinueValue(smsTeacherTitleResp,titleList);
                    continue;
                }
                //获取该组织下的用户id集合
                List<String> userIdList = smsOrgUserRelations.stream().map(SmsOrgUserRelation::getUserId).collect(Collectors.toList());
                //匹配用户id 查询其中符合教师的id集合
                List<String> tchIdList = userTeacherRelationMapper.selectList(new LambdaQueryWrapper<SmsUserTeacherRelation>()
                        .in(SmsUserTeacherRelation::getUserId, userIdList)).stream().map(SmsUserTeacherRelation::getTchId).collect(Collectors.toList());
                if (tchIdList.isEmpty()) {
                    getContinueValue(smsTeacherTitleResp,titleList);
                    continue;
                }
                QueryWrapper<SmsTeacherInfo> tchCollegeQueryWrapper = new QueryWrapper<>();
                tchCollegeQueryWrapper
                        .select("count(*) as titleSum,tch_title as tchTitle")
                        .lambda()
                        .in(SmsTeacherInfo::getId, tchIdList)
                        .groupBy(SmsTeacherInfo::getTchTitle);
                List<Map<String, Object>> maps = smsTeacherInfoMapper.selectMaps(tchCollegeQueryWrapper);
                if (maps.isEmpty()) {
                    getContinueValue(smsTeacherTitleResp,titleList);
                    continue;
                }
            List<SmsTeacherTitleAndSumResp> teacherTitleAndSumList = new ArrayList<>();
            List<SmsTeacherTitleAndSumResp> teacherTitleAndSums = JSON.parseArray(JSON.toJSONString(maps), SmsTeacherTitleAndSumResp.class);
            for (String title : titleList) {
                //匹配相同的职称
                List<SmsTeacherTitleAndSumResp> teacherTitleAndSumResps =
                        teacherTitleAndSums.stream().filter(i -> i.getTchTitle().equals(title)).collect(Collectors.toList());
                SmsTeacherTitleAndSumResp teacherTitleAndSum = new SmsTeacherTitleAndSumResp();
                if (!teacherTitleAndSumResps.isEmpty()) {
                    //职称和职称数量
                    if (isNullOrEmpty(teacherTitleAndSumResps.get(0).getTchTitle())) {
                        teacherTitleAndSum.setTitleSum(teacherTitleAndSumResps.get(0).getTitleSum());//职称数量
                        teacherTitleAndSum.setTchTitle("暂无");//职称
                    } else {
                        teacherTitleAndSum.setTitleSum(teacherTitleAndSumResps.get(0).getTitleSum());//职称数量
                        teacherTitleAndSum.setTchTitle(teacherTitleAndSumResps.get(0).getTchTitle());//职称
                    }
                    //未匹配的先设为暂无,或者其他职称
                } else {
                    if(isNullOrEmpty(title)){
                        teacherTitleAndSum.setTchTitle("暂无");
                    }else {
                        teacherTitleAndSum.setTchTitle(title);//职称
                    }
                    teacherTitleAndSum.setTitleSum(0);//职称数量
                }
                teacherTitleAndSumList.add(teacherTitleAndSum);
            }
            smsTeacherTitleResp.setTeacherTitleAndSum(teacherTitleAndSumList);
        }

        return CommonResult.success(teacherTitleList);
    }

    //在结束之前为各院系的职称赋值
    private void getContinueValue( SmsTeacherTitleResp smsTeacherTitleResp,List<String> titleList){
        List<SmsTeacherTitleAndSumResp> teacherTitleAndSumList = new ArrayList<>();
        for (String title : titleList) {
            SmsTeacherTitleAndSumResp teacherTitleAndSum = new SmsTeacherTitleAndSumResp();
            if(isNullOrEmpty(title)){
                teacherTitleAndSum.setTitleSum(0);//职称数量
                teacherTitleAndSum.setTchTitle("暂无");//职称
            }else {
                teacherTitleAndSum.setTitleSum(0);//职称数量
                teacherTitleAndSum.setTchTitle(title);//职称
            }
            teacherTitleAndSumList.add(teacherTitleAndSum);
        }
        smsTeacherTitleResp.setTeacherTitleAndSum(teacherTitleAndSumList);
    }

    //查询历年的学生和教师人数
    private List<SmsTeachersOverviewResp> getThisYearStudentAndTeacherSum(Integer beginInt, Integer endInt, String professional) {
        List<SmsTeachersOverviewResp> teachersOverviewList = new ArrayList<>();
        //循环年份 填加数据
        while (beginInt <= endInt){
            SmsTeachersOverviewResp teachersOverviewResp = new SmsTeachersOverviewResp();
            //教师总数
            int teacherSum = 0;
            QueryWrapper<SmsTeacherInfo> teacherQueryWrapper = new QueryWrapper<>();
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, beginInt);
            calendar.set(Calendar.MONTH,11);
            Date endDate = TimeUtil.GetEndDateOfMonth(calendar.getTime());
            //查询beginInt这一年的总量
            teacherQueryWrapper
                    .select("count(*) as teacherSum")
                    .lambda()
                    .le(SmsTeacherInfo::getCreateTime,endDate)
                    .groupBy(SmsTeacherInfo::getCreateTime)
                    .orderByAsc(SmsTeacherInfo::getCreateTime);
            List<Map<String, Object>> maps = smsTeacherInfoMapper.selectMaps(teacherQueryWrapper);
            if (maps != null && maps.size() > 0) {
                for (Map<String, Object> map : maps) {
                    SmsTeachersOverviewResp smsTeachersOverviewResp = JSONObject.parseObject(JSONObject.toJSONString(map), SmsTeachersOverviewResp.class);
                    if(!isNullOrEmpty(smsTeachersOverviewResp)) {
                        teacherSum += smsTeachersOverviewResp.getTeacherSum();
                    }
                }
                //如果beginInt没有新增人 则统计之前的总数
            }
            teachersOverviewResp.setTeacherSum(teacherSum);
            //学生总数
            int studentSum = 0;
            QueryWrapper<SmsStudentInfo> studentQueryWrapper = new QueryWrapper<>();
            //前两年的数据
            ArrayList<String> gradeList = new ArrayList<>();
            String beginIntGrade = beginInt + "级";
            String before2 = (beginInt - 2) + "级";
            String before1 = (beginInt - 1) + "级";
            gradeList.add(beginIntGrade);
            gradeList.add(before2);
            gradeList.add(before1);
            studentQueryWrapper
                    .select("count(*) as studentSum")
                    .lambda()
                    .in(SmsStudentInfo::getStuGrade, gradeList)
                    .groupBy(SmsStudentInfo::getStuGrade)
                    .orderByAsc(SmsStudentInfo::getStuGrade);
            if(!isNullOrEmpty(professional)){
                studentQueryWrapper.lambda().eq(SmsStudentInfo::getStuMajor,professional);
            }
            List<Map<String, Object>> studentMaps = smsStudentInfoMapper.selectMaps(studentQueryWrapper);
            if (studentMaps != null && studentMaps.size() > 0) {
                for (Map<String, Object> studentMap : studentMaps) {
                    SmsTeachersOverviewResp smsTeachersOverviewResp = JSONObject.parseObject(JSONObject.toJSONString(studentMap), SmsTeachersOverviewResp.class);
                    if (!isNullOrEmpty(smsTeachersOverviewResp)) {
                        studentSum += smsTeachersOverviewResp.getStudentSum();
                    }
                }
            }
            teachersOverviewResp.setStudentSum(studentSum);
            teachersOverviewResp.setThisYear(String.valueOf(beginInt));
            teachersOverviewList.add(teachersOverviewResp);
            teachersOverviewResp.setSum(studentSum + teacherSum);//总数
            beginInt ++;
        }
        return teachersOverviewList;
    }


    @Override
    public ResponseResult getBoyAndGirlRation() {
        QueryWrapper<SmsStudentInfo> studentInfoQueryWrapper = new QueryWrapper<>();
        SmsStudentBoyAndGirlRationResp studentBoyAndGirlRationResp = new SmsStudentBoyAndGirlRationResp();
        studentInfoQueryWrapper.
                select("SUM(CASE WHEN stu_sex = '女' THEN 1 ELSE 0 END) girlSum,SUM(CASE WHEN stu_sex = '男' THEN 1 ELSE 0 END) boySum,stu_sex as sex")
                .lambda()
                .groupBy(SmsStudentInfo::getStuSex);
        List<Map<String, Object>> maps = smsStudentInfoMapper.selectMaps(studentInfoQueryWrapper);
        int boySum = 0;
        int girlSum = 0;
        if(maps != null && maps.size() > 0){
            for (Map<String, Object> map : maps) {
                SmsStudentBoyAndGirlSumResp smsStudentBoyAndGirlSumResp = JSON.parseObject(JSON.toJSONString(map), SmsStudentBoyAndGirlSumResp.class);
                if(!isNullOrEmpty(smsStudentBoyAndGirlSumResp)) {
                    String sex = smsStudentBoyAndGirlSumResp.getSex();
                    if (!isNullOrEmpty(sex)) {
                        if (sex.equals(STU_SEX_BOY)) {
                            boySum = smsStudentBoyAndGirlSumResp.getBoySum();
                        } else if (sex.equals(STU_SEX_GIRL)) {
                            girlSum = smsStudentBoyAndGirlSumResp.getGirlSum();
                        } else {
                            boySum = smsStudentBoyAndGirlSumResp.getBoySum();
                            girlSum = smsStudentBoyAndGirlSumResp.getGirlSum();
                        }
                    }
                }
            }

        }
        int sum = boySum + girlSum;
        if(sum == 0){
            studentBoyAndGirlRationResp.setBoySumRation(0);
            studentBoyAndGirlRationResp.setGirlSumRation(0);
        }else {
            double boyRatio = Math.ceil((double) boySum / sum * 100);
            double girlRatio = Math.floor((double) girlSum / sum * 100);
            studentBoyAndGirlRationResp.setBoySumRation((int)boyRatio);
            studentBoyAndGirlRationResp.setGirlSumRation((int)girlRatio);
        }
        return CommonResult.success(studentBoyAndGirlRationResp);

    }
}
